package engine;

public class PhysicsFunctions {

	/**
	 * Computes the magnitude of the velocity based on initial velocity, acceleration and time
	 * @param initial initial velocity, magnitude
	 * @param accel acceleration of the object
	 * @param time time elapsed
	 * @return the magnitude of the velocity of the object
	 */
	/*
	 * @ assignable \nothing;
	 * @ returns float;
	 */
	static public float velocity(float initial, float accel, float time)
	{
		return initial+(accel*time);
	}
	/**
	 * Computes the acceleration of an object based on it's current velocity, initial velocity and time elapsed
	 * @param initial the initial velocity's magnitude
	 * @param velocity the current velocity's magnitude
	 * @param time the elapsed time
	 * @return the acceleration the object is experiencing
	 */
	/*
	 * @ requires time!=0;
	 * @ assignable \nothing
	 * @returns float
	 */
	static public float accel(float initial, float velocity, float time)
	{
		return (velocity -initial)/time;
	}
	
	
	/**
	 * Computes the time elapsed based on the initial velocity, current velocity and acceleration 
	 * @param initial the initial velocity of the object
	 * @param velocity the current velocity of the object
	 * @param accel the acceleration acting on the object
	 * @return the elapsed time based on the change in velocity
	 */
	/*
	 * @requires accel!=0;
	 * @returns float;
	 * @ assignable \nothing;
	 */
	static public float time(float initial, float velocity, float accel)
	{
		return (velocity-initial)/accel;
	}
	/**
	 * Computes the new position of a point based on its starting point, velocity, elapsed time and acceleration
	 * @param initialPos the starting position of the point
	 * @param initialVel the initial velocity of the point
	 * @param time the time elapsed
	 * @param accel the acceleration acting on the point
	 * @return the new position of the point
	 */
	/*
	 * @requires initialPos!=null;
	 * @requires initialVel!=null;
	 * @requires accel!=null;
	 * @returns new Vector;
	 * @ assignable \nothing;
	 */
	static public Vector position(Vector initialPos, Vector initialVel, float time, Vector accel)
	{
		Vector pos = new Vector(0, 0);
		pos.setX((float) (initialPos.getX()+(initialVel.getX()*time)+(.5*(accel.getX()*time*time))));
		pos.setY((float) (initialPos.getY()+(initialVel.getY()*time)+(.5*(accel.getY()*time*time))));
		
		return pos;
	}
	
	/**
	 * Computes the force acting on an object based on its mass and acceleration
	 * @param mass the mass of the object
	 * @param accel the acceleration of the object
	 * @return the strength force acting on the object
	 */
	/*
	 * @returns float;
	 * @assignable \nothing;
	 */
	static public float force(float mass, float accel)
	{
		return mass*accel;
	}
	/**
	 * Computes the mass of an object based on its acceleration and the force it exerts
	 * @param accel the acceleration acting on the object
	 * @param force the force the object exerts
	 * @return the mass of the object
	 */
	/*
	 * @returns float;
	 * @assignable \nothing;
	 */
	static public float mass(float accel, float force)
	{
		return force/accel;
	}
	/**
	 * Computes the acceleration of an object based on its mass and the force it exerts
	 * @param mass mass of the object
	 * @param force the force the object exerts
	 * @return the acceleration of the object
	 */
	/*
	 * @returns float;
	 * @assignable \nothing;
	 * @requires time!=0;
	 */
	static public float accel(float mass, float force)
	{
		return force / mass;
	}
	/**
	 * Computes the momentum of an object based on its mass and current 2-D velocity vector
	 * @param mass the mass of the object
	 * @param velocity the current velocity of the vector 
	 * @return the current momentum of the object
	 */
	/*
	 * @requires velocity!=null;
	 * @returns new Vector;
	 * @assignable \nothing;
	 */
	static public Vector momentum(float mass, Vector velocity)
	{
		return new Vector(velocity.getX()*mass,velocity.getY()*mass);
	}
	/**
	 * Computes the velocity of an object based on its momentum and mass
	 * @param momentum the current momentum of the object
	 * @param mass the mass of the object
	 * @return the current velocity of the object
	 */
	/*
	 * @requires momentum!=null;
	 * @returns new Vector
	 * @requires mass!=0;
	 * @assignable \nothing;
	 */
	static public Vector velocity(Vector momentum, float mass)
	{
		return new Vector(momentum.getX()/mass,momentum.getY()/mass);
	}
	/**
	 * Computes the mass of the object based on its current mementum and velocity
	 * @param momentum the object's current momentum
	 * @param velocity the object's current velocity
	 * @return the mass of the object
	 */
	/*
	 * @requires momentum!=null;
	 * @requires velocity!=null;
	 * @returns float;
	 * @assignable \nothing
	 * @requires velocity.magnitude()!=0;
	 */
	static public float mass(Vector momentum, Vector velocity)
	{
		return momentum.magnitude()/velocity.magnitude();
	}
	/**
	 * Computes the kinetic energy of an object
	 * @param mass the mass of the object
	 * @param velocity the current velocity of the object
	 * @return the current kinetic energy of the object
	 */
	/*
	 * @returns float
	 * @assignable \nothing
	 */
	static public float kineticEnergy(float mass, Vector velocity)
	{
		return (float) (.5*mass*(Math.pow(velocity.magnitude(), 2)));
	}
	/**
	 * Computes the total rotational inertia of an object
	 * @param p1 the object in question
	 * @return the object's rotational inertia
	 */
	/*
	 * @returns float;
	 * @requires p1!=null;
	 * @assignable \nothing;
	 */
	static public float rotationalInertia(PhysicsObject p1)
	{
		float inertia = 0;
		Vector center = p1.getCenterOfMass();
		float mass = p1.getMass();
		for(Vertex v : p1.getVertexList())
		{
			inertia+=mass*Math.pow(Vector.dist(center, v.getPos()),2);
		}
		
		return inertia;
	}
}
